﻿using Opc.Ua;
using Opc.Ua.Client;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.Service.OpcService;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SHRIS.MIS.Service.Device
{
    public class Manipulator_09 : BasicDevice
    {
        private readonly IEnumerable<OpcDataSourceEntity> _opcDataSourceEntities;
        public Manipulator_09(DeviceEntity deviceEntity,
           WorkshopCommunicationService workshopCommunicationService,
           IEnumerable<OpcDataSourceEntity> opcDataSourceEntities)
           : base(deviceEntity, workshopCommunicationService)
        {
            _opcDataSourceEntities = opcDataSourceEntities;
            CheckOutDataType();
        }

        private void CheckOutDataType()
        {
            //对所有OPC 数据类型进行校验，如果不对记入LOG

        }

        public override void InitalDevice()
        {
            //创建opc 订阅

            //找出该通道下的订阅数据，dataAction==4 为订阅
            var subscriptionDatas = _opcDataSourceEntities.Where(i => i.DataAction == 4);

            //找出订阅数据的服务器列表
            var serverIds = subscriptionDatas.Select(i => i.ServerId).Distinct().ToList();

            if (serverIds.Count() == 1)
            {
                _workshopCommunicationService.CreateOpcSubscription(subscriptionDatas, DataHandler);
            }


            //用deviceCode作为订阅组名字
            //var subscriptionName = _deviceEntity.DeviceCode;

        }

        private void DataHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                //Console.WriteLine(notification.Value.StatusCode.ToString());

                if (notification != null)
                {
                    Guid dataId = new Guid();
                    bool isId = Guid.TryParse(monitoredItem.DisplayName, out dataId);
                    if (isId && (!dataId.IsGuidNullOrEmpty()))
                    {
                        var dataSource = _opcDataSourceEntities.Where(i => i.Id == dataId).First();
                        switch (dataSource.DataName)
                        {
                            case "RestartStatus":
                                {
                                    RestartStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO":
                                {
                                    EMO = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready":
                                {
                                    Ready = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    HasWorkpiece = (bool)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    WorkpieceSource = (short)notification.Value.Value;
                                    break;
                                }
                            case "Grab01":
                                {
                                    Grab01 = (short)notification.Value.Value;
                                    break;
                                }
                            case "Grab02":
                                {
                                    Grab02 = (short)notification.Value.Value;
                                    break;
                                }
                            case "Put01":
                                {
                                    Put01 = (short)notification.Value.Value;
                                    break;
                                }
                            case "Put02":
                                {
                                    Put02 = (short)notification.Value.Value;
                                    break;
                                }
                            case "Position":
                                {
                                    Position = (short)notification.Value.Value;
                                    break;
                                }
                            case "mStatus":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MStatus = new BitArray(b);
                                    break;
                                }
                            case "mAlarm1":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MAlarm1 = new BitArray(b);
                                    break;
                                }
                            case "mAlarm2": {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MAlarm2 = new BitArray(b);
                                    break;
                                }
                            case "MaterialCode_G1":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        MaterialCode_G1 = notification.Value.Value.ToString();
                                    }
                                    break;
                                }
                            case "MaterialCode_G2":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        MaterialCode_G2=notification.Value.Value.ToString();
                                    }
                                    break;
                                }
                            case "RbStartEquTime":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        RbStartEquTime = DateTimeOffset.Parse(notification.Value.Value.ToString());
                                    }
                                    break;
                                }
                            case "HasAlarm":
                                {
                                    HasAlarm = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AtAuto":
                                {
                                    AtAuto = (bool)notification.Value.Value;
                                    break;
                                }
                            case "MaunalT1":
                                {
                                    MaunalT1 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "ManualT2":
                                {
                                    ManualT2 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AtInitPosition":
                                {
                                    AtInitPosition = (bool)notification.Value.Value;
                                    break;
                                }
                            default:
                                {
                                    break;
                                }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region 设备参数     

        private bool hasAlarm;
        /// <summary>
        /// 机器人存在报警
        /// </summary>
        public bool HasAlarm
        {
            get
            {
                return hasAlarm;
            }
            set
            {
                bool previewVlaue = hasAlarm;
                hasAlarm = value;
                OnPropertyChanged("HasAlarm", previewVlaue, hasAlarm);
            }
        }

        private bool atAuto;
        /// <summary>
        /// 机器人自动模式
        /// </summary>
        public bool AtAuto
        {
            get
            {
                return atAuto;
            }
            set
            {
                bool previewVlaue = atAuto;
                atAuto = value;
                OnPropertyChanged("AtAuto", previewVlaue, atAuto);
            }
        }

        private bool maunalT1;
        /// <summary>
        /// 手动T1模式
        /// </summary>
        public bool MaunalT1
        {
            get
            {
                return maunalT1;
            }
            set
            {
                bool previewVlaue = maunalT1;
                maunalT1 = value;
                OnPropertyChanged("MaunalT1", previewVlaue, maunalT1);
            }
        }

        private bool manualT2;
        /// <summary>
        /// 手动T2模式
        /// </summary>
        public bool ManualT2
        {
            get
            {
                return manualT2;
            }
            set
            {
                bool previewVlaue = manualT2;
                manualT2 = value;
                OnPropertyChanged("ManualT2", previewVlaue, manualT2);
            }
        }

        private bool atInitPosition;
        /// <summary>
        /// 机器人在原位
        /// </summary>
        public bool AtInitPosition
        {
            get
            {
                return atInitPosition;
            }
            set
            {
                bool previewVlaue = atInitPosition;
                atInitPosition = value;
                OnPropertyChanged("AtInitPosition", previewVlaue, atInitPosition);
            }
        }

        private BitArray mStatus;
        /// <summary>
        /// 机器人状态字
        /// DB7.DBB48
        /// </summary>
        public BitArray MStatus
        {
            get
            {
                return mStatus;
            }
            set
            {
                BitArray previewVlaue = mStatus;
                mStatus = value;
                OnPropertyChanged("MStatus", previewVlaue, mStatus);
            }
        }

        private BitArray mAlarm1;
        /// <summary>
        /// 机器人报警字1
        /// DB7.DBB50
        /// </summary>
        public BitArray MAlarm1
        {
            get
            {
                return mAlarm1;
            }
            set
            {
                BitArray previewVlaue = mAlarm1;
                mAlarm1 = value;
                OnPropertyChanged("MAlarm1", previewVlaue, mAlarm1);
            }
        }

        private BitArray mAlarm2;
        /// <summary>
        /// 机器人报警字2
        /// DB7.DBB52
        /// </summary>
        public BitArray MAlarm2
        {
            get
            {
                return mAlarm2;
            }
            set
            {
                BitArray previewVlaue = mAlarm2;
                mAlarm2 = value;
                OnPropertyChanged("MAlarm2", previewVlaue, mAlarm2);
            }
        }

        private string materialCode_G1;
        /// <summary>
        /// 物料码抓手1
        /// DB7.DBB54
        /// </summary>
        public string MaterialCode_G1
        {
            get
            {
                return materialCode_G1;
            }
            set
            {
                string previewVlaue = materialCode_G1;
                materialCode_G1 = value;
                OnPropertyChanged("MaterialCode_G1", previewVlaue, materialCode_G1);
            }
        }

        private string materialCode_G2;
        /// <summary>
        /// 物料码抓手2
        /// DB7.DBB96
        /// </summary>
        public string MaterialCode_G2
        {
            get
            {
                return materialCode_G2;
            }
            set
            {
                string previewVlaue = materialCode_G2;
                materialCode_G2 = value;
                OnPropertyChanged("MaterialCode_G2", previewVlaue, materialCode_G2);
            }
        }

        private DateTimeOffset rbStartEquTime;
        /// <summary>
        /// 机器人本次开机时刻
        /// DB7.DBB138
        /// </summary>
        public DateTimeOffset RbStartEquTime
        {
            get
            {
                return rbStartEquTime;
            }
            set
            {
                DateTimeOffset previewVlaue = rbStartEquTime;
                rbStartEquTime = value;
                OnPropertyChanged("RbStartEquTime", previewVlaue, rbStartEquTime);
            }
        }

        private double rbRunningTime;
        /// <summary>
        /// 机器人开机时间，永不清零（单位:小时）
        /// DB7.DBD146
        /// </summary>
        public double RbRunningTime
        {
            get
            {
                return rbRunningTime;
            }
            set
            {
                double previewVlaue = rbRunningTime;
                rbRunningTime = value;
                OnPropertyChanged("RbRunningTime", previewVlaue, rbRunningTime);
            }
        }

        private bool restartStatus;
        public bool RestartStatus
        {
            get
            {
                return restartStatus;
            }
            set
            {
                bool previewVlaue = restartStatus;
                restartStatus = value;
                OnPropertyChanged("RestartStatus", previewVlaue, restartStatus);
            }
        }

        private bool eMO;
        public bool EMO
        {
            get
            {
                return eMO;
            }
            set
            {
                bool previewVlaue = eMO;
                eMO = value;
                OnPropertyChanged("EMO", previewVlaue, eMO);
            }
        }

        private bool ready;
        public bool Ready
        {
            get
            {
                return ready;
            }
            set
            {
                bool previewVlaue = ready;
                ready = value;
                OnPropertyChanged("Ready", previewVlaue, ready);
            }
        }

        private bool codeBypassStatus;
        public bool CodeBypassStatus
        {
            get
            {
                return codeBypassStatus;
            }
            set
            {
                bool previewVlaue = codeBypassStatus;
                codeBypassStatus = value;
                OnPropertyChanged("CodeBypassStatus", previewVlaue, codeBypassStatus);
            }
        }

        private bool end;
        public bool End
        {
            get
            {
                return end;
            }
            set
            {
                bool previewVlaue = end;
                end = value;
                OnPropertyChanged("End", previewVlaue, end);
            }
        }

        private bool sasWorkpiece;
        public bool HasWorkpiece
        {
            get
            {
                return sasWorkpiece;
            }
            set
            {
                bool previewVlaue = sasWorkpiece;
                sasWorkpiece = value;
                OnPropertyChanged("HasWorkpiece", previewVlaue, sasWorkpiece);
            }
        }

        private short workpieceSource;
        public short WorkpieceSource
        {
            get
            {
                return workpieceSource;
            }
            set
            {
                short previewVlaue = workpieceSource;
                workpieceSource = value;
                OnPropertyChanged("WorkpieceSource", previewVlaue, workpieceSource);
            }
        }

        private short grab01;
        public short Grab01
        {
            get
            {
                return grab01;
            }
            set
            {
                short previewVlaue = grab01;
                grab01 = value;
                OnPropertyChanged("Grab01", previewVlaue, grab01);
            }
        }

        private short grab02;
        public short Grab02
        {
            get
            {
                return grab02;
            }
            set
            {
                short previewVlaue = grab02;
                grab02 = value;
                OnPropertyChanged("Grab02", previewVlaue, grab02);
            }
        }

        private short put01;
        public short Put01
        {
            get
            {
                return put01;
            }
            set
            {
                short previewVlaue = put01;
                put01 = value;
                OnPropertyChanged("Put01", previewVlaue, put01);
            }
        }

        private short put02;
        public short Put02
        {
            get
            {
                return put02;
            }
            set
            {
                short previewVlaue = put02;
                put02 = value;
                OnPropertyChanged("Put02", previewVlaue, put02);
            }
        }

        private short position;
        public short Position
        {
            get
            {
                return position;
            }
            set
            {
                short previewVlaue = position;
                position = value;
                OnPropertyChanged("Position", previewVlaue, position);
            }
        }
        #endregion
    }
}
